bitkeeper revision 1.160.1.2 (3e8ca5d6NuIwQ-85rqA_rDQ3WcxL2A)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Thu, 3 Apr 2003 21:21:26 +0000 (21:21 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Thu, 3 Apr 2003 21:21:26 +0000 (21:21 +0000)
mm.h, xen_block.c, memory.c:
  Changed the page-typing fix around; it at least _looks_ a bit more generic now :-)

xen/common/memory.c
xen/drivers/block/xen_block.c
xen/include/xeno/mm.h

index e6139b00e55c217da6df24f6cb10de5cc081d0d3..c39b1ae862b7507f7e30c9371d504e06cd5d9323 100644 (file)
@@ -441,7 +441,7 @@ static int get_page(unsigned long page_nr, int writeable)
             page->flags &= ~PG_type_mask;
             page->flags |= PGT_writeable_page;
         }
-        page->flags &= ~PG_noflush;
+        page->flags |= PG_need_flush;
         get_page_type(page);
     }
 
@@ -500,9 +500,13 @@ static void put_page(unsigned long page_nr, int writeable)
     ASSERT(DOMAIN_OKAY(page->flags));
     ASSERT((!writeable) || 
            ((page_type_count(page) != 0) && 
-            ((page->flags & PG_type_mask) == PGT_writeable_page)));
+            ((page->flags & PG_type_mask) == PGT_writeable_page) &&
+            ((page->flags & PG_need_flush) == PG_need_flush)));
     if ( writeable && (put_page_type(page) == 0) )
+    {
         tlb_flush[smp_processor_id()] = 1;
+        page->flags &= ~PG_need_flush;
+    }
     put_page_tot(page);
 }
 
index 8901ee59fbad0963877c4c117f3ace09823dc032..441ee090283d338470463865f2dcc31bd8aef5ed 100644 (file)
@@ -306,9 +306,9 @@ static void __lock_buffer(unsigned long buffer,
         {
             if ( page->type_count == 0 )
             {
-                page->flags &= ~PG_type_mask;
+                page->flags &= ~(PG_type_mask | PG_need_flush);
                 /* NB. This ref alone won't cause a TLB flush. */
-                page->flags |= PGT_writeable_page | PG_noflush;
+                page->flags |= PGT_writeable_page;
             }
             get_page_type(page);
         }
@@ -332,11 +332,11 @@ static void unlock_buffer(struct task_struct *p,
         page = frame_table + pfn;
         if ( writeable_buffer &&
              (put_page_type(page) == 0) &&
-             !(page->flags & PG_noflush) )
+             (page->flags & PG_need_flush) )
         {
             __flush_tlb();
+            page->flags &= ~PG_need_flush;
         }
-        page->flags &= ~PG_noflush;
         put_page_tot(page);
     }
     spin_unlock_irqrestore(&p->page_lock, flags);
index 6a2e2e939698ed8bd08dc238b1df69c6fde0a6d8..f71255f9710b80d7309b3f2469cb276e515bbdc9 100644 (file)
@@ -98,17 +98,17 @@ typedef struct pfn_info {
 #define PGT_net_rx_buf      (8<<24) /* this page has been pirated by the net code. */
 
 /*
- * This bit is sometimes set by Xen when it holds a writeable reference to a 
- * page that shouldn't cause a TLB flush when it is dropped. For example, a 
- * disk write to a page with initial type_count == 0, which returns to 0 after 
- * the I/O. In this case, we'd normally flush the TLB because a writeable page 
- * has just lost its mutually-exclusive type. But this isn't necessary here 
- * because the writeable reference never made it into user-accessible TLB 
- * (didn't make it into TLB at all, in fact).
+ * This bit indicates that the TLB must be flushed when the type count of this
+ * frame drops to zero. This is needed on current x86 processors only for
+ * frames which have guestos-accessible writeable mappings. In this case we must 
+ * prevent stale TLB entries allowing the frame to be written if it used for a
+ * page table, for example.
  * 
- * This bit is obviously nuked in a few places, for safety.
+ * We have this bit because the writeable type is actually also used to pin a page
+ * when it is used as a disk read buffer. This doesn't require a TLB flush because
+ * the frame never has a mapping in the TLB.
  */
-#define PG_noflush          (1<<28)
+#define PG_need_flush       (1<<28)
 
 #define PageSlab(page)         test_bit(PG_slab, &(page)->flags)
 #define PageSetSlab(page)      set_bit(PG_slab, &(page)->flags)